Nucleo

您所在的位置:网站首页 if ll Nucleo

Nucleo

2024-06-09 19:46| 来源: 网络整理| 查看: 265

Nucleo-F411RE (STM32F411)LL库体验 7 - 低功耗(睡眠) 1、简述

F411有三种模式 Sleep mode、stop mode 、standby mode。 其中SleepMode 、Stop Mode 可选择WFI 以及WFE,两者的区别在于,前者任何中断都能唤醒,后者只能是Wakeup Event才能唤醒。 唤醒时接着进入睡眠处的代码继续执行。 借助之前的letter shell,我们添加pwr命令,输入pwr --sleep 进入sleep mode, 输入pwr --stop 进入stop mode。每次进入睡眠跟唤醒之前,灯会快速闪烁。 这里选择进入__WFI,承接前一章,我们将Blue Button设置为了中断,mcu进入睡眠后,我们按一下按键,可唤醒mcu。

2、按键中断设置

前一章讲过,这里只把重要代码贴一下。

/** * @brief This function configures EXTI Line as Push-Button * @note Peripheral configuration is minimal configuration from reset values. * @param None * @retval None */ static void BOARD_UserButtonConfigureEXTI() { /* -1- GPIO Config */ /* Enable GPIO Clock (to be able to program the configuration registers) */ USER_BUTTON_GPIO_CLK_ENABLE(); /* Configure IO */ LL_GPIO_SetPinMode(USER_BUTTON_GPIO_PORT, USER_BUTTON_PIN, LL_GPIO_MODE_INPUT); LL_GPIO_SetPinPull(USER_BUTTON_GPIO_PORT, USER_BUTTON_PIN, LL_GPIO_PULL_NO); /* -2- Connect External Line to the GPIO*/ USER_BUTTON_SYSCFG_SET_EXTI(); /*-3- Enable a falling trigger EXTI line 13 Interrupt */ USER_BUTTON_EXTI_LINE_ENABLE(); USER_BUTTON_EXTI_FALLING_TRIG_ENABLE(); /*-4- Configure NVIC for EXTI15_10_IRQn */ NVIC_EnableIRQ(USER_BUTTON_EXTI_IRQn); NVIC_SetPriority(USER_BUTTON_EXTI_IRQn,0); }

定义:

/** * @brief Key push-button */ #define USER_BUTTON_PIN LL_GPIO_PIN_13 #define USER_BUTTON_GPIO_PORT GPIOC #define USER_BUTTON_GPIO_CLK_ENABLE() LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC) #define USER_BUTTON_EXTI_LINE LL_EXTI_LINE_13 #define USER_BUTTON_EXTI_IRQn EXTI15_10_IRQn #define USER_BUTTON_EXTI_LINE_ENABLE() LL_EXTI_EnableIT_0_31(USER_BUTTON_EXTI_LINE) #define USER_BUTTON_EXTI_FALLING_TRIG_ENABLE() LL_EXTI_EnableFallingTrig_0_31(USER_BUTTON_EXTI_LINE) #define USER_BUTTON_SYSCFG_SET_EXTI() do { \ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG); \ LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTC, LL_SYSCFG_EXTI_LINE13); \ } while(0) #define USER_BUTTON_IRQHANDLER EXTI15_10_IRQHandler

中断处理函数,唤醒睡眠用

/** * @brief This function handles external line 13 interrupt request. * @param None * @retval None */ void USER_BUTTON_IRQHANDLER(void) { /* Manage Flags */ if(LL_EXTI_IsActiveFlag_0_31(USER_BUTTON_EXTI_LINE) != RESET) { LL_EXTI_ClearFlag_0_31(USER_BUTTON_EXTI_LINE); } if (LL_GPIO_IsInputPinSet(USER_BUTTON_GPIO_PORT,USER_BUTTON_PIN) == 0) { printf("key press\r\n"); } } 3、sleepMode 、StopMode、StandbyMode #include "power_mode.h" /** * @brief Function to configure and enter in STOP_MAINREGU Mode. * @param None * @retval None */ void EnterSTOP_MAINREGUMode(void) { /** Request to enter STOP_MAINREGU mode * Following procedure describe in STM32F4xx Reference Manual * See PWR part, section Low-power modes, STOP_MAINREGU mode */ /* Set STOP_MAINREGU mode when CPU enters deepsleep */ LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_LPREGU); /* Set SLEEPDEEP bit of Cortex System Control Register */ LL_LPM_EnableDeepSleep(); /* Request Wait For Interrupt */ __WFI(); } void Enter_SleepMode(void) { /* Set SLEEPDEEP bit of Cortex System Control Register */ LL_LPM_EnableDeepSleep(); /* Request Wait For Interrupt */ __WFI(); } void EnterStandbyMode(void) { /* Disable all used wakeup sources */ LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN1); /* Clear all wake up Flag */ LL_PWR_ClearFlag_WU(); /* Enable wakeup pin */ LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN1); /** Request to enter STANDBY mode * Following procedure describe in STM32F4xx Reference Manual * See PWR part, section Low-power modes, Standby mode */ /* Set STANDBY mode when CPU enters deepsleep */ LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY); /* Set SLEEPDEEP bit of Cortex System Control Register */ LL_LPM_EnableDeepSleep(); /* This option is used to ensure that store operations are completed */ #if defined ( __CC_ARM) __force_stores(); #endif /* Request Wait For Interrupt */ __WFI(); } 4、Letter Shell命令添加

这里用了linux的getopt_long函数来解析参数,这个比较常用的,如果不明白,请百度。 输入pwr -I,显示当前设备信息,如下: 在这里插入图片描述 输入 pwr --sleep,灯会快速函数,然后进入睡眠。 在这里插入图片描述 输入pwr --stop 进入停机模式 在这里插入图片描述 输入 pwr --standby 进入待机模式,但是这里的唤醒可不是蓝色按键了,而是PA0,待机后,将PA0接3.3v即可唤醒。 在这里插入图片描述 在这里插入图片描述

另外,睡眠不能在中断函数里处理,shell串口的收数据是在中断里,所以不能解析到命令直接进入sleep mode,这里设置了一个变量,main的while循环里去进入sleep mode。

#include "extend_shell.h" #include "power_mode.h" #include "shell_port.h" #include #include #include "getopt.h" volatile uint8_t blinkMode = 200; volatile uint8_t sleepMode = 0; void PWR_ShowUsage(void) { printf("Usage:\r\n"); printf(" pwr (-h | --help)\r\n"); printf(" pwr (-i | --info)\r\n"); printf(" pwr (--sleep) enter sleep mode \r\n"); printf(" pwr (--stop) enter stop mode \r\n"); printf(" pwr (--standby) enter standby mode \r\n"); } void PWR_ShowInfomation(void) { LL_RCC_ClocksTypeDef rccClock; LL_RCC_GetSystemClocksFreq(&rccClock); printf("Nucleo-F411RE Info:\r\n"); printf(" Version : %s %s\r\n",__DATE__,__TIME__); printf(" System Clock : %ld\r\n",rccClock.SYSCLK_Frequency); printf(" AHB Clock : %ld\r\n",rccClock.HCLK_Frequency); printf(" APB1 Clock : %ld\r\n",rccClock.PCLK1_Frequency); printf(" APB2 Clock : %ld\r\n",rccClock.PCLK2_Frequency); } int PWR_Control(int argc,char *argv[]) { int c; int longindex = 0; const char short_options[] = "hi"; const struct option long_options[] = { {"help", 0, NULL, 'h'}, {"info", 0, NULL, 'i'}, {"sleep", 0, NULL, 1}, {"stop", 0, NULL, 2}, {"standby", 0, NULL, 3}, {NULL, 0, NULL, 0}, }; if (argc == 1) { /* goto the help */ PWR_ShowUsage(); return 0; } /* init 0 */ optind = 0; opterr = 0; /* parse */ do { /* parse the args */ c = getopt_long(argc, argv, short_options, long_options, &longindex); switch (c) { case 'h'/* constant-expression */: /* code */ PWR_ShowUsage(); return 0; case 'i': PWR_ShowInfomation(); break; case 1: /* for sleep mode */ printf("Now enter Sleep Mode\r\n"); sleepMode = 1; break; case 2: /* for sleep mode */ printf("Now enter Stop Mode\r\n"); sleepMode = 2; break; case 3: /* for sleep mode */ sleepMode = 3; printf("Now enter Standby Mode\r\n"); break; default: break; } }while (c != -1); return 0; } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), pwr, PWR_Control, PWR_Control);

main函数:

#include "main.h" #include "board_init.h" #include "clock_init.h" #include "stdio.h" #include "systick.h" #include "power_mode.h" #include "shell_port.h" #include "extend_shell.h" void LED_Blinking_5s(void) { uint32_t i = 0; /* Toggle IO in during 5s (25*200ms) */ for(i = 0; i < 25; i++) { LL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN); BOARD_Delay1Ms(50); } } void Configure_PWR(void) { /* Enable Power Clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); /* Check if the system was resumed from StandBy mode */ if (LL_PWR_IsActiveFlag_SB() != 0) { /* Clear Standby flag */ LL_PWR_ClearFlag_SB(); /* Change LED speed to SLOW to indicate exit from standby mode */ printf("mcu the system was resumed from StandBy mode \r\n"); } /* Check and Clear the Wakeup flag */ if (LL_PWR_IsActiveFlag_WU() != 0) { LL_PWR_ClearFlag_WU(); } } int main(void) { BOARD_Init(); Configure_PWR(); User_Shell_Init(); while (1) { if (sleepMode == 0) { LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5); } else if (sleepMode == 1) { sleepMode = 0; LED_Blinking_5s(); LED_OFF(); Enter_SleepMode(); BOARD_Init(); LED_Blinking_5s(); printf("Now From Sleep Mode\r\n"); } else if (sleepMode == 2) { sleepMode = 0; LED_Blinking_5s(); LED_OFF(); EnterSTOP_MAINREGUMode(); BOARD_Init(); LED_Blinking_5s(); printf("Now From Stop Mode\r\n"); } else if (sleepMode == 3) { sleepMode = 0; LED_Blinking_5s(); LED_OFF(); EnterStandbyMode(); } /* Insert delay 250 ms */ BOARD_Delay1Ms(blinkMode); } } 5、代码

代码下载



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3